package xyz.bali16.module.rank.schedules;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gitee.starblues.bootstrap.annotation.AutowiredType;
import com.gitee.starblues.spring.MainApplicationContext;
import com.gitee.starblues.spring.SpringBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import xyz.bali16.application.core.utils.RedisUtil;
import xyz.bali16.module.article.entity.Article;
import xyz.bali16.module.article.service.ArticleService;
import xyz.bali16.module.rank.service.ArticleRankServiceCaller;


import java.util.ArrayList;
import java.util.List;
import java.util.Set;


/**
 * 帖子访问量已经设置成先存缓存后存数据库
 * 避免热帖访问对帖子save操作过多，导致数据库繁忙
 */
@Component
@EnableAsync
@EnableScheduling
public class ViewCountSyncTask {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    ArticleRankServiceCaller articleRankServiceCaller;

    @Scheduled(cron = "0/5 * * * * *") //每分钟同步
    public void task() {
        System.out.println("定时任务启动——刷新排行榜");
        // 获取前缀所有rank:post的数据
        Set<String> keys = redisTemplate.keys("rank:article:*");
        List<String> ids = new ArrayList<>();
        System.out.println("keys!");
        // rank:article:e78dec8a1b5a481199ad98e060bceed3
        System.out.println(keys);
        for (String key : keys) {
            // 查看是否有article:viewCount值
            if(redisTemplate.opsForHash().hasKey(key, "article:views")){
                // 通过substring获取前缀后的内容
                ids.add(key.substring("rank:article:".length()));
            }
        }
        System.out.println(ids);
        // 如果没有数据 任务结束
        if(ids.isEmpty()) return;

        // 根据所获取的缓存帖子id进行查询
        List<Article> posts = articleRankServiceCaller.supperList(ids);
        // 更新缓存帖子中的访问量
        System.out.println("posts!");
        System.out.println(posts);
        posts.stream().forEach((post) ->{
            Integer views = (Integer) redisTemplate.opsForHash().get("rank:article:" + post.getId(), "article:views");
            post.setViews(views);
        });

        if(posts.isEmpty()) return;
        // 批量更新帖子
        boolean isSucc = articleRankServiceCaller.supperUpdateById(posts);
        // 如果成功更新就将更新的帖子访问量key给删掉，这里整个操作不是原子性的，所以有可能会漏掉一些访问量，数据敏感的话注意这个功能。
        if(isSucc) {
            ids.stream().forEach((id) -> {
                redisTemplate.opsForHash().delete("rank:article:" + id, "article:views");
                System.out.println(id + "---------------------->同步成功");
            });
        }
    }

}
